package com.jzo2o.foundations.service.impl;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.jzo2o.foundations.model.dto.response.ServeSimpleResDTO;
import com.jzo2o.foundations.service.ServeAggregationService;
import lombok.RequiredArgsConstructor;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author itlxc
 * @since 2024-10-17
 */
@Service
@RequiredArgsConstructor
public class ServeAggregationServiceImpl implements ServeAggregationService {

    private final RestHighLevelClient restHighLevelClient;


    /**
     * 首页服务搜索
     * @param cityCode    城市编码
     * @param serveTypeId 服务类型id
     * @param keyword     关键词
     * @return
     * @throws IOException
     */
    @Override
    public List<ServeSimpleResDTO> findServeList(String cityCode, Long serveTypeId, String keyword) throws IOException {
        // 1.创建SearchRequest对象
        SearchRequest request = new SearchRequest("serve_aggregation");
        // 2.构建查询条件
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        if (StrUtil.isNotBlank(keyword)) {
            boolQuery.must(QueryBuilders.multiMatchQuery(keyword, "serve_item_name", "serve_type_name"));
        }
        if (StrUtil.isNotBlank(cityCode)) {
            boolQuery.filter(QueryBuilders.termQuery("city_code", cityCode));
        }
        if (ObjectUtil.isNotNull(serveTypeId)) {
            boolQuery.filter(QueryBuilders.termQuery("serve_type_id", serveTypeId));
        }
        SearchSourceBuilder searchSourceBuilder = request.source();
        searchSourceBuilder.query(boolQuery);
        // 3.排序条件
        searchSourceBuilder.sort("serve_item_sort_num", SortOrder.ASC);
        // 4.发送请求，执行查询
        SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        // 5.解析响应数据并返回
        return parserResponse(response);
    }

    /**
     * 解析响应数据
     * @param response
     * @return
     */
    private List<ServeSimpleResDTO> parserResponse(SearchResponse response) {
        SearchHit[] searchHits = response.getHits().getHits();
        if (ArrayUtil.isEmpty(searchHits)) {
            return Collections.emptyList();
        }
        List<ServeSimpleResDTO> serveSimpleResDTOList = new ArrayList<>(searchHits.length);
        for (SearchHit searchHit : searchHits) {
            String source = searchHit.getSourceAsString();
            ServeSimpleResDTO serveSimpleResDTO = JSONUtil.toBean(source, ServeSimpleResDTO.class);
            serveSimpleResDTOList.add(serveSimpleResDTO);
        }
        return serveSimpleResDTOList;
    }


}
